+2008-03-11 Tor Lillqvist <tml@novell.com>
+
+ Bug 469868 - Filenames with colon ":" are not saved correctly
+
+ * gtk/gtkfilechooserentry.c (insert_text_callback)
+ (delete_text_callback) [Win32]: New functions to make sure that
+ colons used otherwise than as a separator after a drive letter, or
+ characters that are always illegal in file names, are rejected on
+ input. This means that the GTK+ file chooser can't be used to
+ input full names of alternate data streams, but oh well. There are
+ still more checks that could be done on the file names, see the
+ bug report. But this will do for now.
+ (_gtk_file_chooser_entry_init) [Win32]: Connect above functions.
+
2008-03-11 Jordi Mallach <jordi@sindominio.net>
* configure.in (ALL_LINGUAS): Add ca@valencia (Valencian-Catalan).
static void clear_completion_callback (GtkFileChooserEntry *chooser_entry,
GParamSpec *pspec);
+
+#ifdef G_OS_WIN32
+static gint insert_text_callback (GtkFileChooserEntry *widget,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data);
+static void delete_text_callback (GtkFileChooserEntry *widget,
+ gint start_pos,
+ gint end_pos,
+ gpointer user_data);
+#endif
+
static gboolean match_selected_callback (GtkEntryCompletion *completion,
GtkTreeModel *model,
GtkTreeIter *iter,
G_CALLBACK (clear_completion_callback), NULL);
g_signal_connect (chooser_entry, "notify::selection-bound",
G_CALLBACK (clear_completion_callback), NULL);
+
+#ifdef G_OS_WIN32
+ g_signal_connect (chooser_entry, "insert_text",
+ G_CALLBACK (insert_text_callback), NULL);
+ g_signal_connect (chooser_entry, "delete_text",
+ G_CALLBACK (delete_text_callback), NULL);
+#endif
}
static void
}
}
+#ifdef G_OS_WIN32
+static gint
+insert_text_callback (GtkFileChooserEntry *chooser_entry,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data)
+{
+ const gchar *colon = memchr (new_text, ':', new_text_length);
+ gint i;
+
+ /* Disallow these characters altogether */
+ for (i = 0; i < new_text_length; i++)
+ {
+ if (new_text[i] == '<' ||
+ new_text[i] == '>' ||
+ new_text[i] == '"' ||
+ new_text[i] == '|' ||
+ new_text[i] == '*' ||
+ new_text[i] == '?')
+ break;
+ }
+
+ if (i < new_text_length ||
+ /* Disallow entering text that would cause a colon to be anywhere except
+ * after a drive letter.
+ */
+ (colon != NULL &&
+ *position + (colon - new_text) != 1) ||
+ (new_text_length > 0 &&
+ *position <= 1 &&
+ GTK_ENTRY (chooser_entry)->text_length >= 2 &&
+ gtk_entry_get_text (GTK_ENTRY (chooser_entry))[1] == ':'))
+ {
+ gtk_widget_error_bell (GTK_WIDGET (chooser_entry));
+ g_signal_stop_emission_by_name (chooser_entry, "insert_text");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+delete_text_callback (GtkFileChooserEntry *chooser_entry,
+ gint start_pos,
+ gint end_pos,
+ gpointer user_data)
+{
+ /* If deleting a drive letter, delete the colon, too */
+ if (start_pos == 0 && end_pos == 1 &&
+ GTK_ENTRY (chooser_entry)->text_length >= 2 &&
+ gtk_entry_get_text (GTK_ENTRY (chooser_entry))[1] == ':')
+ {
+ g_signal_handlers_block_by_func (chooser_entry,
+ G_CALLBACK (delete_text_callback),
+ user_data);
+ gtk_editable_delete_text (GTK_EDITABLE (chooser_entry), 0, 1);
+ g_signal_handlers_unblock_by_func (chooser_entry,
+ G_CALLBACK (delete_text_callback),
+ user_data);
+ }
+}
+#endif
+
/**
* _gtk_file_chooser_entry_new:
* @eat_tabs: If %FALSE, allow focus navigation with the tab key.